﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Bizspoke.BizTalk.Brma;
using Microsoft.BizTalk.Tracking;
using System.IO;
using System.Collections;
using Bizspoke.BizTalk.Adapter;

namespace Bizspoke.BizTalk.HATPlugIn.BizTalk.Extension.HATPlugIn
{
    public partial class ProgressForm : Form
    {
        private List<TrackedInstance> trackedInstances;
        private string outputFolder;
        private string viewName;
        private ICollection items;
        private BackgroundWorker worker;

        private delegate void GenericMethodDelegate();
        private delegate void SetProgressBarMaxDelegate(int max);
        private delegate void ProgressChangedDelegate(TrackedInstance trackedInstance, int count);

        public string OutputFolder
        {
            get { return outputFolder; }
        }

        public List<TrackedInstance> TrackedInstances
        {
            get { return trackedInstances; }
        }

        public ProgressForm()
        {
            InitializeComponent();
        }

        public ProgressForm(string viewName, ICollection items)
        {
            InitializeComponent();
            this.viewName = viewName;
            this.items = items;
        }

        private void SaveMessages()
        {
            //OutputFolder = new DirBrowser().RequestFolderLocationWithChecks();
            this.outputFolder = Path.Combine(Path.GetTempPath(), "Bizspoke");
            this.outputFolder = Path.Combine(this.outputFolder, "HATPlugIn");

            /*if (Directory.Exists(OutputFolder))
            {
                try
                {
                    Directory.Delete(OutputFolder, true);
                }
                catch { }
            }*/

            if (!Directory.Exists(this.outputFolder))
                Directory.CreateDirectory(this.outputFolder);

            Admin admin = new Admin();
            this.trackedInstances = new List<TrackedInstance>();
            int count = 1;

            //SetProgressBarMax(this.items.Count);

            foreach (TrackingDataItem item in this.items)
            {
                if (worker.CancellationPending)
                    break;

                Dictionary<string, TrackingProperty> trkprops = new Dictionary<string, TrackingProperty>();
                foreach (TrackingProperty prop in item.TrackingProperties)
                    trkprops.Add(prop.DisplayName, prop);

                string serviceInstanceId = trkprops["ServiceInstance/InstanceID"].Value.ToString();
                string activityId = trkprops["ServiceInstance/ActivityID"].Value.ToString();
                string dataType = "";

                TrackedInstance trackedInstance = admin.SaveAllMessagesToFile(Info.BtsTrackingDBServer, Info.BtsTrackingDBName, Info.BtsMgmtDBServer, Info.BtsMgmtDBServer, Info.BtsMgmtDBName, serviceInstanceId, activityId, dataType, this.outputFolder);
                trackedInstance.TrackingProperties = trkprops;
                trackedInstances.Add(trackedInstance);

                worker.ReportProgress(CalculatePercent(count, this.items.Count), trackedInstance);

                count++;
            }
        }

        private void SetProgressBarMax(int max)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new SetProgressBarMaxDelegate(SetProgressBarMax), max);
                return;
            }
            progressBar1.Maximum = max;
        }

        private void UpdateProgress(TrackedInstance trackedInstance, int percent)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new ProgressChangedDelegate(UpdateProgress), trackedInstance, percent);
                return;
            }

            labServiceName.Text = trackedInstance.TrackingProperties["Service/Name"].Value.ToString();
            labServiceType.Text = trackedInstance.TrackingProperties["Service/Type"].Value.ToString();
            labServiceInstanceID.Text = trackedInstance.TrackingProperties["ServiceInstance/InstanceID"].Value.ToString();
            labActivityID.Text = trackedInstance.TrackingProperties["ServiceInstance/ActivityID"].Value.ToString();

            foreach (TrackedMessage tm in trackedInstance.TrackedMessages)
            {
                string imageKey = (tm.Status == "Saved") ? "Status_Success.ico" : "Status_Failure.ico";
                ListViewItem lvItem = listView1.Items.Add(labServiceName.Text, imageKey);
                lvItem.SubItems.Add(labServiceType.Text);
                lvItem.SubItems.Add(labServiceInstanceID.Text);
                lvItem.SubItems.Add(tm.Status);
            }
                        
            listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);

            this.Text = string.Format("Retrieving message {1} of {2} - {0}%", percent, (int)((percent * this.items.Count) / 100), this.items.Count);
            progressBar1.Value = percent;

            Application.DoEvents();
        }

        private int CalculatePercent(int value, int total)
        {
            double dblvalue = (double)value;
            double dbltotal = (double)total;
            double dblpercent = (dblvalue * 100) / dbltotal;
            return (int)dblpercent;
        }

        private void ProgressForm_Load(object sender, EventArgs e)
        {
            worker = new BackgroundWorker();
            worker.WorkerReportsProgress = true;
            worker.WorkerSupportsCancellation = true;

            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);

            labServiceName.Text = "";
            labServiceType.Text = "";
            labServiceInstanceID.Text = "";
            labActivityID.Text = "";

            worker.RunWorkerAsync(worker);
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            switch (this.viewName)
            {
                case "ViewSaved":
                    break;
                default:
                    SaveMessages();
                    break;
            }
        }

        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            UpdateProgress((TrackedInstance)(e.UserState), e.ProgressPercentage);
            //if (this.InvokeRequired)
            //    this.Invoke(new ProgressChangedDelegate(UpdateProgress), e.UserState, e.ProgressPercentage);
        }

        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (this.InvokeRequired)
                this.Invoke(new GenericMethodDelegate(Close));
            else
                Close();
        }

        private void ProgressForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!this.worker.IsBusy)
            {
                this.DialogResult = DialogResult.OK;
            }
            else if (this.worker.IsBusy || this.worker.CancellationPending)
            {
                this.DialogResult = DialogResult.Abort;
                //e.Cancel = true;
            }
        }

    }
}
